package com.qf.fmall2202.user.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.fmall2202.ex.QFException;
import com.qf.fmall2202.user.entity.User;
import com.qf.fmall2202.user.service.IUsersService;
import com.qf.fmall2202.utils.CommonConstants;
import com.qf.fmall2202.utils.R;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/**
 * <p>
 * 用户  前端控制器
 * </p>
 *
 * @author dong_
 * @since 2022-11-03
 */
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UsersController {

    @Autowired
    IUsersService usersService;

    @GetMapping("/login")
    public R login(String username,String password) throws JsonProcessingException {

        //1. 获取 shiro 的 subject 对象
        final Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username,password));
        } catch (AuthenticationException e) {
            throw new QFException("用户名或者密码错误");
        }

        final User user = (User) subject.getPrincipal();

        // 生成服务器端的token，用于后续的请求验证用户的身份
        String token = createToken(user);

        //2. 返回json
        return R.ok(token).put("data", user);

    }

    /**
     * 创建token字符串
     * 对于token的需求
     * (1) 要能够让服务器端校验token是否合法（是不是服务器端办法的token）
     * (2) 时效性 （能够指定过期时机）
     * (3) 扩展性，可以自定义存入token中的信息
     * @param user
     * @return
     */
    private String createToken(User user) throws JsonProcessingException {

        final JwtBuilder builder = Jwts.builder();

        final HashMap<String, Object> map = new HashMap<>();

        // user ---> json
        final ObjectMapper objectMapper = new ObjectMapper();
        final String userJson = objectMapper.writeValueAsString(user);

        map.put(CommonConstants.JWT_CLAIMS_KEY,userJson);

        final String jwt = builder.setClaims(map) // 自定义数据
                .setSubject(user.getUsername())
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setIssuer(CommonConstants.JWT_AUTHOR)
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
                .signWith(SignatureAlgorithm.HS256, CommonConstants.JWT_SECRET_KEY)
                .compact();

        return jwt;
    }

    @PostMapping("/regist")
    public R regist(@RequestBody User user){

        User u = usersService.regist(user);

        return R.ok().put("data", u);

    }



}
